#ifndef SCREENINGMOLA_H
#define SCREENINGMOLA_H

#include "../misc/MODEL.H"
#include <vector>
#define MOLAS_SEMAFORO

using namespace std;
class SPHERE;
class MODEL;
class ScreeningMola
{			// Algoritmo adaptado do Screening
    private:

        double CellSize;
        SPHERE***Cell;
        ELEMENT_LIST<SPHERE>* Spheres;				// Elementos
        ELEMENT_LIST<SPRING>* Springs;				// Elementos
        int Rows;
        int Cols;
        REAL MinR[2];						// Fronteiras
        REAL MaxR[2];
        bool valorDaVez;
        MODEL *md;
        #ifndef MOLAS_SEMAFORO
        vector<SPRING*> molasDistantes;
        #endif
        #ifdef MOLAS_SEMAFORO
        vector<SPRING*> *molasDistantes;
        #endif
        void iniciaMatriz( REAL max_rad, REAL min_r[2], REAL max_r[2] );
        void CriaMatriz();
        void CriaMatrizParalelo();
        void checkSprings(SPHERE *s);
        void ProcessaDistantes();
        void checkSprings(SPHERE *s,int linha,int coluna);

        inline double Min( double x, double y ) { return (x < y)? x : y; }
        inline double Max( double x, double y ) { return (x > y)? x : y; }
	public:

        ScreeningMola()
        {
            Spheres = NULL;
            MinR[0] = MinR[1] = MaxR[0] = MaxR[1] = 0.0;
            Cell = NULL;
        }
        ScreeningMola (REAL max, MODEL *pModel)
        {
            md=pModel;
            Cell = NULL;
            assert (&pModel->SPHList!=NULL);
            assert (&pModel->SPRList!=NULL);
            Spheres = &pModel->SPHList;
            Springs = &pModel->SPRList;
            iniciaMatriz( max,pModel->BoxMin, pModel->BoxMax );
            valorDaVez=1;
            if (Springs!=NULL) for(SPRING* k = Springs->Begin; k != NULL;k = k->Next)
            {
                k->foiAcessado=0;
            }
        }

        ~ScreeningMola() {

            /*
            for (int i = 0; i <= Rows+1; i++)
            {
                for (int j = 0; j <= Cols+1; j++)
                {
                    Cell[i][j].clear();
                }
            }*/
            if (Cell != NULL) {
                for (long i = 0; i < Rows+2; i++) delete [] Cell[i];
                delete [] Cell;
            }
            #ifdef MOLAS_SEMAFORO
            for (SPRING* s = Springs->Begin; s != NULL;s = s->Next) omp_destroy_lock(&(s->semaforo));
            #endif
            delete md;
            delete Spheres;
            delete Springs;
        }


        void calcular();
};

#endif // SCREENINGMOLA_H
